/**
 * @file useExpression
 * @author  fanxl
 * @description 动态表达式 isRemove-移除节点（Model层存在Field，视图层不Render）；isHidden（Model层存在Field，视图层Render但不占线）
 */
import {get} from 'lodash-es';
import {useRegistOption} from './useRegistOption';
import {useFormInject} from './useForm';
import {useRegistField} from './useRegistField';
import {computed, watch, unref, reactive} from 'vue';
import type {ComputedRef} from 'vue';
import {getChildSpecInitValue, getDefaultValue} from '../util/spec';
import type {LikeFieldType} from '../interface/field';

export function useExpression(
    fieldProps: ComputedRef<LikeFieldType> | LikeFieldType,
    fieldName: ComputedRef<string> | string
) {
    const form = useFormInject();
    const values = computed(() => form.values);
    const registerOption = useRegistOption(fieldProps, values);
    const isRemove = computed(() => registerOption.isRemove);
    const isHidden = computed(() => registerOption.isHidden);
    const spec = computed(() => [unref(fieldProps).spec]);
    const parentPath = computed(() => unref(fieldName).split('.').slice(0, -1).join('.'));

    watch(isRemove, (value: boolean) => {
        form.setInlineExpressState(unref(fieldName), 'isRemove', value);
        if (value) {
            form.deleteFieldValue(unref(fieldName));
            const targetKeys = Object.keys(form.fieldRegistry).filter((v) => v.startsWith(unref(fieldName)));
            targetKeys.forEach((fieldName) => {
                form.unregisterField(fieldName);
            });
        } else {
            const defaultValue = getDefaultValue(registerOption.spec);
            const initValue = getChildSpecInitValue(registerOption.spec, defaultValue, form.values, unref(fieldName));
            form.setFieldValue(unref(fieldName), get(initValue, registerOption.spec.name));
            useRegistField(spec, form, unref(parentPath));
        }
    });

    watch(isHidden, (value: boolean) => {
        form.setInlineExpressState(unref(fieldName), 'isHidden', value);
    });

    return reactive({
        isRemove,
        isHidden
    });
}
